/*
 * Copyright 2011 group coding kata nantes
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package fr.coding.kata.nantes.bench.countword;

import fr.coding.kata.nantes.bench.AbstractRunner;
import fr.coding.kata.nantes.bench.Couple;
import fr.coding.kata.nantes.countwords.commons.KataCountWordsInterface;
import fr.coding.kata.nantes.countwords.sylvain.CountWordUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * Benchmark runner for the "Count Word" kata implementations.
 *
 * @author Sylvain Leduby
 * @since 1.0
 */
public class CountWordRunner extends AbstractRunner<KataCountWordsInterface, CountWordData, Integer> {

    public static final String EOL = System.getProperty("line.separator");

    /**
     * Logger.
     */
    private static final Logger LOG = LoggerFactory.getLogger(CountWordRunner.class);

    /**
     * Implementations to run.
     */
    private static final List<KataCountWordsInterface> IMPLS;

    static {
        IMPLS = new ArrayList<KataCountWordsInterface>();
        IMPLS.add(new KataCountWordsRef());
        // add your implementation here
        IMPLS.add(new fr.coding.kata.nantes.countwords.christophe.KataCountWords());
        //IMPLS.add(new KataCountWordsJDK7());
        //IMPLS.add(new KataCountWordsMultiThread());
        IMPLS.add(new fr.coding.kata.nantes.countwords.sylvain.KataCountWords().caseSensitive());

    }

    public CountWordRunner() {
        super(IMPLS, getData());
    }

    @Override
    public KataCountWordsInterface init(final KataCountWordsInterface target, final CountWordData input) {
        return target.withWord(input.word).withText(input.text);
    }

    private static List<Couple<CountWordData, Integer>> getData() {
        final List<Couple<CountWordData, Integer>> dataset = new ArrayList<Couple<CountWordData, Integer>>();

        StringBuilder allTextBuilder = new StringBuilder();

        final int testCount = 100;
        for (int i = 0; i < testCount; i++) {
            LOG.info("Generating {}/{}", i + 1, testCount);
            final String word = CountWordUtil.generateRandomWord();
            final String text = CountWordUtil.generate(word, CountWordUtil.generateRandomInteger());
            final CountWordData input = new CountWordData(word, text);

            allTextBuilder.append(text).append(EOL);

            // real count (the word could be contained by other generated words)
            final Integer occurrences = StringUtils.countMatches(text, word);

            dataset.add(new Couple<CountWordData, Integer>(input, occurrences));
        }

        String allText = allTextBuilder.toString();
        final String word = CountWordUtil.generateRandomWord();
        final Integer occurrences = StringUtils.countMatches(allText, word);

        dataset.add(new Couple<CountWordData, Integer>(new CountWordData(word, allText), occurrences));


        return dataset;
    }

}
